package world.snowcrystal.openapi.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import world.snowcrystal.commons.exception.BusinessException;
import world.snowcrystal.commons.model.entity.UserInvokeLog;
import world.snowcrystal.commons.model.enums.ApplicationResponseStatusCode;
import world.snowcrystal.commons.service.UserInvokeLogService;
import world.snowcrystal.openapi.exception.ThrowUtils;
import world.snowcrystal.openapi.mapper.UserInvokeLogMapper;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author shoak
 * @description 针对表【user_invoke_log】的数据库操作Service实现
 * @createDate 2024-10-19 10:46:11
 */
@Service
public class UserInvokeLogServiceImpl extends ServiceImpl<UserInvokeLogMapper, UserInvokeLog>
        implements UserInvokeLogService {

    private Lock readLock ;
    private Lock writeLock;

    private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    {
        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        readLock = lock.readLock();
        writeLock = lock.writeLock();
    }

    @Override
    public void validUserInvokeLog(UserInvokeLog userInvokeLog, boolean add) {

        if (userInvokeLog == null) {
            throw new BusinessException(ApplicationResponseStatusCode.PARAMS_ERROR, "用户调用记录不存在");
        }


        Long id = userInvokeLog.getId();
        Long userId = userInvokeLog.getUserId();
        Long interfaceId = userInvokeLog.getInterfaceId();
        Integer invokeCount = userInvokeLog.getInvokeCount();
        Integer remainingInvokeTimes = userInvokeLog.getRemainingInvokeTimes();
        Integer status = userInvokeLog.getStatus();
        Integer isDelete = userInvokeLog.getIsDelete();


        if (add) {
            ThrowUtils.throwIf(id == null || userId == null, ApplicationResponseStatusCode.PARAMS_ERROR, "用户调用记录id或用户id不能为空");
        }
        ThrowUtils.throwIf(remainingInvokeTimes != null && remainingInvokeTimes <= 0, ApplicationResponseStatusCode.PARAMS_ERROR, "分配的剩余调用次数不能小于0");
        ThrowUtils.throwIf(status != null && status < 0, ApplicationResponseStatusCode.PARAMS_ERROR);
        ThrowUtils.throwIf(isDelete != null && isDelete == 1, ApplicationResponseStatusCode.NOT_FOUND_ERROR, "用户调用记录已被删除");
    }

    @Override
    public boolean increaseInvokeCount(long interfaceId, long userId) {

        if (interfaceId <= 0 || userId <= 0) {
            throw new BusinessException(ApplicationResponseStatusCode.PARAMS_ERROR, "接口id或用户id不能小于等于0");
        }
        UpdateWrapper<UserInvokeLog> updateWrapper = new UpdateWrapper<>();
        updateWrapper
                .eq("interfaceId", interfaceId)
                .eq("userId", userId)
                .eq("isDelete", 0)
                .eq("status", 0)
                .gt("remainingInvokeTimes", 0)
                .setSql("invokeCount = invokeCount + 1, remainingInvokeTimes = remainingInvokeTimes - 1");
        writeLock.lock();
        final boolean result = this.update(updateWrapper);
        writeLock.unlock();
        return result;
    }
}




